﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Zj.CourseManage.Domain.Core;
using Zj.CourseManage.DTO.Common;
using Zj.CourseManage.DTO.Common.Pagination;
using Microsoft.AspNetCore.Authorization;
using Zj.CourseManage.Domain.Events;
using Zj.CourseManage.Domain.Students;

namespace Zj.CourseManage.Mvc.Controllers
{
    public class StudentsController : Controller
    {
        private DbContext _ctx;
        private IEventBus _eventBus;
        public StudentsController(
            DbContext ctx,
            IEventBus eventBus)
        {
            this._ctx = ctx;
            this._eventBus = eventBus;
        }
        // GET: Students
        //[IgnoreAntiforgeryToken]
        public IActionResult Index(string SearchString, string sortName = "", int? pageIndex = 1, int pageSize = 3)
        {
            var list = _ctx.Set<Student>().AsNoTracking();
            if (!string.IsNullOrWhiteSpace(SearchString))
            {
                list = list.Where(s => s.Name.Contains(SearchString));
            }
            ViewData["sortName"] = sortName == "" ? "NameDesc" : "";
            ViewData["sortBirthday"] = sortName == "Birthday" ? "BirthdayDesc" : "Birthday";
            ViewData["searchString"] = SearchString;
            ViewData["pageIndex"] = pageIndex;
            switch (sortName)
            {
                case "NameDesc":
                    list = list.OrderByDescending(s => s.Name);
                    break;
                case "Birthday":
                    list = list.OrderBy(s => s.Birthday);
                    break;
                case "BirthdayDesc":
                    list = list.OrderByDescending(s => s.Birthday);
                    break;
                default:
                    list = list.OrderBy(s => s.Name);
                    break;
            }
            //var _list = await list.ToListAsync();
            var _list = PaginatedList<Student>.CreatePaging(list, (int)pageIndex, pageSize);
            var dtoList = _list.Select(s => new StudentDTO() { Name = s.Name, Birthday = s.Birthday, Introduction = s.Introduction, Id = s.Id }).ToList();
            return View(_list);
        }

        // GET: Students/Details/5
        public ActionResult Details(int id)
        {
            return View();
        }

        // GET: Students/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Students/Create
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(StudentDTO dto)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    // TODO: Add insert logic here
                    Student stu = new Student() { Name = dto.Name, Birthday = dto.Birthday, Introduction = dto.Introduction };
                    _ctx.Add(stu);
                    await _eventBus.PublishAsync(new StudentCreatedEvent(stu.Name));
                    await _ctx.SaveChangesAsync();
                }
                return RedirectToAction(nameof(Index));
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "添加学生异常，请检查信息，然后重试");
                return View();
            }
        }

        // GET: Students/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var stu = await _ctx.Set<Student>().AsNoTracking().FirstOrDefaultAsync(s => s.Id == id);
            if (stu == null)
            {
                return NotFound();
            }
            StudentDTO dto = new StudentDTO() { Name = stu.Name, Birthday = stu.Birthday, Introduction = stu.Introduction };
            ViewBag.Id = id;
            return View(dto);
        }

        // POST: Students/Edit/5
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int? id, StudentDTO dto)
        {
            try
            {
                if (id == null)
                {
                    return NotFound();
                }
                var stu = await _ctx.Set<Student>().AsNoTracking().FirstOrDefaultAsync(s => s.Id == id);
                if (stu == null)
                {
                    return NotFound();
                }
                stu.Name = dto.Name;
                stu.Birthday = dto.Birthday;
                stu.Introduction = dto.Introduction;
                _ctx.Update(stu);
                await _ctx.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch
            {
                return View();
            }
        }

        // GET: Students/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var stu = await _ctx.Set<Student>().AsNoTracking().FirstOrDefaultAsync(s => s.Id == id);
            if (stu == null)
            {
                return NotFound();
            }
            _ctx.Remove(stu);
            await _ctx.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
    }
}